package com.monitor.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.monitor.dao.ErpClientsMapper;
import com.monitor.dao.ErpClientsMaterielDetailsMapper;
import com.monitor.dao.ErpClientsMaterielMapper;
import com.monitor.dao.ErpCustomerMapper;
import com.monitor.dao.ErpCustomerWarehouseMapper;
import com.monitor.dao.ErpFlowClientsMapper;
import com.monitor.dao.ErpManagementMapper;
import com.monitor.dao.ErpMaterielFlowMapper;
import com.monitor.dao.ErpMaterielFlowMaterielDetailsMapper;
import com.monitor.dao.ErpMaterielFlowMaterielMapper;
import com.monitor.dao.ErpMaterielFlowSummaryMapper;
import com.monitor.dao.ErpMaterielMapper;
import com.monitor.dao.ErpOrderdMapper;
import com.monitor.dao.ErpOrderdMaterielMapper;
import com.monitor.dao.ErpSystemMessageMapper;
import com.monitor.dao.ErpTireArchivesWorkMapper;
import com.monitor.dao.ErpUserMapper;
import com.monitor.dao.ErpWarehouseMapper;
import com.monitor.entity.ErpClients;
import com.monitor.entity.ErpClientsMateriel;
import com.monitor.entity.ErpClientsMaterielDetails;
import com.monitor.entity.ErpCustomer;
import com.monitor.entity.ErpCustomerWarehouse;
import com.monitor.entity.ErpFlowClients;
import com.monitor.entity.ErpManagement;
import com.monitor.entity.ErpMateriel;
import com.monitor.entity.ErpMaterielFlow;
import com.monitor.entity.ErpMaterielFlowMateriel;
import com.monitor.entity.ErpMaterielFlowMaterielDetails;
import com.monitor.entity.ErpMaterielFlowSummary;
import com.monitor.entity.ErpOrderd;
import com.monitor.entity.ErpOrderdMateriel;
import com.monitor.entity.ErpSystemMessage;
import com.monitor.entity.ErpTireArchivesWork;
import com.monitor.entity.ErpUser;
import com.monitor.entity.ErpWarehouse;
import com.monitor.service.ErpMaterielFlowService;
import com.monitor.util.DataUtil;
import com.monitor.util.IDUtils;
import com.monitor.util.Result;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 物料流转表 服务实现类
 * </p>
 *
 * @author LX
 * @since 2018-09-08
 */
@Service
public class ErpMaterielFlowServiceImpl extends ServiceImpl<ErpMaterielFlowMapper, ErpMaterielFlow> implements ErpMaterielFlowService {
	@Resource
	private ErpMaterielFlowMapper erpMaterielFlowMapper;
	
	@Resource
	private ErpCustomerMapper erpCustomerMapper;
	
	@Resource
	private ErpCustomerWarehouseMapper erpCustomerWarehouseMapper;
	
	@Resource
	private ErpWarehouseMapper erpWarehouseMapper;
	
	@Resource
	private ErpMaterielFlowMaterielMapper erpMaterielFlowMaterielMapper;
	
	@Resource
	private ErpMaterielMapper erpMaterielMapper;
	
	@Resource
	private ErpMaterielFlowMaterielDetailsMapper erpMaterielFlowMaterielDetailsMapper;
	
	@Resource
	private ErpMaterielFlowSummaryMapper erpMaterielFlowSummaryMapper;
	
	@Resource
	private ErpOrderdMapper erpOrderdMapper;
	
	@Resource
	private ErpClientsMapper erpClientsMapper;
	
	@Resource
	private ErpOrderdMaterielMapper erpOrderdMaterielMapper;
	
	@Resource
	private ErpClientsMaterielMapper erpClientsMaterielMapper;
	
	@Resource
	private ErpClientsMaterielDetailsMapper erpClientsMaterielDetailsMapper;
	
	@Resource
	private ErpFlowClientsMapper erpFlowClientsMapper;
	
	@Resource
	private ErpUserMapper erpUserMapper;
	
	@Resource
	private ErpSystemMessageMapper erpSystemMessageMapper;
	
	@Resource
	private ErpTireArchivesWorkMapper erpTireArchivesWorkMapper;
	
	@Resource
	private ErpManagementMapper erpManagementMapper;

	@Override
	public Result<List<ErpCustomer>> selectHuoByCode(int custId) {
		// TODO Auto-generated method stub
		ErpCustomer customer=erpCustomerMapper.selectById(custId);
		List<ErpCustomer> list=erpCustomerMapper.selectList(new EntityWrapper<ErpCustomer>().like("cus_operate_type", "货运公司").or().like("cus_operate_type", "物流运输").or().eq("cus_code", customer.getCusCode()));
		return new Result<List<ErpCustomer>>(list, list.size());
	}

	@Override
	public Result<List<Map<String, Object>>> selectByWareHouseId(int custId,int custWareId) {
		// TODO Auto-generated method stub
		//ErpCustomer cus = erpCustomerMapper.selectById(custId);
		ErpCustomerWarehouse customerWarehouse = erpCustomerWarehouseMapper.selectById(custWareId);
		List<Map<String, Object>> datas = new ArrayList<Map<String, Object>>();
		if(customerWarehouse ==null){
			return new Result<List<Map<String,Object>>>(datas, 0);
		}else{
			List<ErpWarehouse> wlist = erpWarehouseMapper.selectList(new EntityWrapper<ErpWarehouse>().eq("customer_id", custId).and().eq("warehouse_id", custWareId));
			//List<String> materiel0 = new ArrayList<String>();
			//List<Integer> indexs = new ArrayList<Integer>();
			for(int i = 0; i < wlist.size(); i++ ){
				ErpWarehouse w = wlist.get(i);
				if(w.getMaterielNumber()==null|| w.getMaterielOccupyNumber()==null) {
					
				}else {
					if(w.getMaterielNumber() - w.getMaterielOccupyNumber() < 1){
						//indexs.add(i);
					}else{
						Map<String, Object> map=new HashMap<>();
						map.put("materielName", w.getMaterielName());
						map.put("materielBrand", w.getMaterielBrand());
						map.put("materielSpecifications", w.getMaterielSpecifications());
						map.put("materielModel", w.getMaterielModel());
						map.put("materielPlace", w.getMaterielPlace());
						map.put("materielState", w.getMaterielState());
						map.put("materielUnit", w.getMaterielUnit());
						map.put("num", (w.getMaterielNumber()- w.getMaterielOccupyNumber()));
						map.put("materielId", w.getId());
						//String materiel = w.getMaterielName()+w.getMaterielSpecifications()+w.getMaterielBrand()
						//+w.getMaterielModel()+w.getMaterielPlace()+w.getMaterielState();
						//materiel0.add(materiel);
						datas.add(map);
					}
				}
			}
			//for(Integer i : indexs){
				//wlist.remove(i);
			//}
			return new Result<List<Map<String,Object>>>(datas, datas.size());
		}
	}

	@Override
	public Result<Integer> addMaterielFlow(ErpMaterielFlow mf, String mfmsJson,int userId,int custId) {
		// TODO Auto-generated method stub
		ErpCustomerWarehouse cw = erpCustomerWarehouseMapper.selectByIdAndName(mf.getCustId(), mf.getSourceWarehouseName());
		List<ErpMaterielFlowMateriel> list=JSONObject.parseArray(mfmsJson, ErpMaterielFlowMateriel.class);
		mf.setWarehouseId(-1);
		mf.setFlowDirection(1);
		mf.setTransportInvoice(0);
		mf.setTransportPay(0);
		mf.setTransportReceivables(0);
		mf.setInvoiceState(0);
		mf.setPayState(0);
		erpMaterielFlowMapper.insert(mf);
		Double workMoney=0.00;
		int i=0;
		for(ErpMaterielFlowMateriel mfms:list) {
			if(StringUtils.isNotBlank(mfms.getMaterielName())){
				Integer materielNumber = mfms.getMaterielNumber();
				Double price = mfms.getMaterielPrice();
				Double total = mfms.getMaterielTotal();
				if(materielNumber != null && materielNumber > 0 && price != null && price >0 && total != null && total > 0){
					String materielProductionId = mfms.getMaterielProductionId();
					List<ErpMateriel> materiels = new ArrayList<ErpMateriel>();
					//判断是否指定出库的物料
					if(materielProductionId.equals("0")){
						materiels = this.findMaterielByMateriel(cw.getId(), mfms.getMaterielName(), mfms.getMaterielBrand(), 
									mfms.getMaterielSpecifications(), mfms.getMaterielModel(), mfms.getMaterielPlace(), 
									mfms.getMaterielState(), mfms.getMaterielUnit(), 0, mfms.getMaterielNumber());
					}else{
						//截取物料编码前面的0！
						//materielProductionId = materielProductionId.substring(2,  materielProductionId.length());
						//把！转换为','便于hql语句查询
						materielProductionId = materielProductionId.replace("!", "','");
						//materielProductionId = "'"+materielProductionId+"'";
						//根据物料编码查询
						materiels = erpMaterielMapper.selectInProductionId(materielProductionId+"'");
						//如果编码数量小于出库数量获取没有物料编码的物料
						if(materiels.size() < materielNumber){
							materiels.addAll( this.findMaterielByMateriel(cw.getId(), materiels.get(i).getMaterielName(), materiels.get(i).getMaterielBrand(), 
									materiels.get(i).getMaterielSpecifications(), materiels.get(i).getMaterielModel(), materiels.get(i).getMaterielPlace(), 
									materiels.get(i).getMaterielState(), materiels.get(i).getMaterielUnit(), 0, materielNumber+materiels.size()));
						}
						
					}
					if(materielNumber > materiels.size()){
						materielNumber = materiels.size();
					}
					
					//修改仓库物理数量
					ErpWarehouse ware=new ErpWarehouse();
					ware.setWarehouseId(cw.getId());
					ware.setCustomerId(mf.getCustomerId());
					ware.setMaterielName(materiels.get(i).getMaterielName());
					ware.setMaterielBrand(materiels.get(i).getMaterielBrand());
					ware.setMaterielSpecifications(materiels.get(i).getMaterielSpecifications());
					ware.setMaterielModel( materiels.get(i).getMaterielModel());
					ware.setMaterielPlace(materiels.get(i).getMaterielPlace());
					ware.setMaterielState(materiels.get(i).getMaterielState());
					ware.setMaterielUnit(materiels.get(i).getMaterielUnit());
					ErpWarehouse warehouse = erpWarehouseMapper.selectWareHouse(ware);
					warehouse.setMaterielNumber(warehouse.getMaterielNumber()-materielNumber);
					erpWarehouseMapper.updateById(warehouse);
					ErpMaterielFlowMateriel mfm = new ErpMaterielFlowMateriel();
					mfm.setMaterielFlowId(mf.getId());
					mfm.setMaterielName(materiels.get(i).getMaterielName());
					mfm.setMaterielBrand(materiels.get(i).getMaterielBrand());
					mfm.setMaterielSpecifications(materiels.get(i).getMaterielSpecifications());
					mfm.setMaterielModel(materiels.get(i).getMaterielModel());
					mfm.setMaterielPlace(materiels.get(i).getMaterielPlace());
					mfm.setMaterielState(materiels.get(i).getMaterielState());
					mfm.setMaterielUnit(materiels.get(i).getMaterielUnit());
					mfm.setMaterielNumber(materielNumber);
					mfm.setMaterielPrice(price);
					mfm.setMaterielTotal(total);
					mfm.setMaterielTotalTax(warehouse.getMaterielTax()*materielNumber);
					mfm.setInvoiceType(materiels.get(i).getMaterielInvoiceType()+"");
					erpMaterielFlowMaterielMapper.insert(mfm);
					workMoney += total;
					
					//记录出库的物料
					List<ErpMateriel> materiels0 = new ArrayList<ErpMateriel>();
					//记录出库的附带品
					List<ErpMateriel> materielsFD0 = new ArrayList<ErpMateriel>();
					for(int j=0; j<materielNumber; j++){
						ErpMateriel materiel = materiels.get(j);
						materiel.setWarehouseId(-1);
						erpMaterielMapper.insert(materiel);
						ErpMaterielFlowMaterielDetails mfmd = new ErpMaterielFlowMaterielDetails();
						mfmd.setPid(mfm.getId());
						mfmd.setMaterielId(materiel.getId());
						mfmd.setMaterielStudy(0);
						erpMaterielFlowMaterielDetailsMapper.insert(mfmd);
						materiels0.add(materiel);
						if(materiel.getMaterielName().equals("轮胎")){
							this.updateTireArchives(materiel.getId(), mf, mfm.getMaterielPrice(), 2);
						}else if(materiel.getMaterielName().equals("轮胎(智能)")){
							this.updateTireArchives(materiel.getId(), mf, mfm.getMaterielPrice(), 2);
						}
						materielsFD0.add(null);
					}
					//保存物料流转汇总信息
					ErpMaterielFlowSummary mfs = new ErpMaterielFlowSummary();
					mfs.setWarehouseId(cw.getId());
					mfs.setMaterielId(warehouse.getId());
					mfs.setWorkSheetId(mf.getMaterielFlowSheetId());
					mfs.setMaterielFlowDate(mf.getMaterielFlowDate());
					mfs.setMaterielStorageNumber(0);
					mfs.setMaterielStoragePrice(0.0);
					mfs.setMaterielOutflowNumber(materielNumber);
					mfs.setMaterielOutflowPrice(mfm.getMaterielPrice());
					if(materiels.get(i).getMaterielInvoiceType()==0){
						mfs.setIncludingTax(0);
					}else{
						mfs.setIncludingTax(1);
					}
					mfs.setMaterielFlowType(1);
					mfs.setMaterielRetained(0);
					mfs.setFlowSubject(mf.getFlowType());
					mfs.setMaterielSource(mf.getSourceWarehouseName());
					mfs.setMaterielWhereabouts(mf.getCustomerName());
					mfs.setFlowAttn(mf.getMaterielFlowAttn());
					erpMaterielFlowSummaryMapper.insert(mfs);
					//判断当前出库单为销售出库
					if(mf.getFlowType().equals("销售出库")){
						//this.updateOrderAndClients(materiels0, materielsFD0, mf.getCustomerName(), mf.getCustomerId(), materiels.get(i).getMaterielName(), materiels.get(i).getMaterielBrand(), 
							//	materiels.get(i).getMaterielSpecifications(), materiels.get(i).getMaterielModel(), materiels.get(i).getMaterielPlace(), 
								//materiels.get(i).getMaterielState(), materiels.get(i).getMaterielUnit(), materielNumber, mf.getMaterielFlowSheetId(),userId);
					}
					i++;
				}
			}
		}
		ErpManagement manage=new ErpManagement();
		manage.setDt(mf.getMaterielFlowDate());
		manage.setWorkId(mf.getMaterielFlowSheetId());
		manage.setClientName(mf.getSourceCustomerName());
		manage.setCarNumber(mf.getTransportCar());
		manage.setWorkProject(mf.getFlowType());
		manage.setPurchase(0.0);
		manage.setSail(mf.getAllamount());
		manage.setWorkAttn(mf.getMaterielFlowAttn());
		manage.setKuguanattn(mf.getKuAttn());
		manage.setWorkPlace(mf.getTransportCustomer());
		manage.setCustomerId(custId);
		erpManagementMapper.insert(manage);
		
		ErpSystemMessage message=new ErpSystemMessage();
		message.setCompanys(mf.getSourceCustomerName());
		message.setCreateDt(new Date());
		message.setMessageType(mf.getFlowType());
		message.setPriority("99");
		message.setReceiveUserId(0);
		message.setSendCustId(mf.getSourceCustomerId());
		message.setReceiveCustId(mf.getCustomerId());
		message.setSendContent(mf.getMaterielFlowSheetId());
		message.setSendUserId(0);
		message.setSendUserName(mf.getSourceCustomerName());
		message.setSendFlag("未读");
		erpSystemMessageMapper.insert(message);
		return new Result<Integer>(1, 1);
	}
	
	/**
	 * 根据物料信息查询物料
	 * @param id 仓库id
	 * @param name 品名
	 * @param brands 品牌
	 * @param specifications 规格
	 * @param models 型号
	 * @param places 产地
	 * @param states 状态
	 * @param units 单位
	 * @param load 是否上车
	 * @param count 需求数量
	 * @return
	 */
	public List<ErpMateriel> findMaterielByMateriel(int id, String name, String brands, 
			String specifications, String models, String places, String states, String units, int load, int count){
		List<ErpMateriel> materiels = new ArrayList<ErpMateriel>();
		//获取没有物料编码的物料
		materiels = erpMaterielMapper.findPage( id, name, brands, specifications, models, places, states, units,count);
		//如果没有物料编码的物料数量不足在获取有物料编码并且没有上车的物料
		if(materiels.size() < count){
			materiels.addAll(erpMaterielMapper.findPage( id, name, brands, specifications, models, places, states, units,count-materiels.size()));
		}
		return materiels;
	}
	
	/**
	 * 修改需求汇总和客户采购订单
	 * @param materiels 已出库的物料
	 * @param customerName 客户名称
	 * @param id 当前客户id
	 * @param name 品名
	 * @param brand 品牌
	 * @param specifications 规格
	 * @param model 型号
	 * @param place 产地
	 * @param state 状态
	 * @param unit 单位
	 * @param materielNumber 数量
	 * @return
	 */
	public boolean updateOrderAndClients(List<ErpMateriel> materiels, List<ErpMateriel> materielsFD, String customerName, int id, String name, String brand, 
			String specifications, String model, String place, String state, String unit, int materielNumber, String XSCKSheetId,int userId){
		//查询是否有为未出库的需求
		List<Map<String, Object>> orderds = erpOrderdMapper.selectByGroupAndCustId(customerName, id);
		if(orderds.size() > 0){
			int materielindex = 0;
			a:
			for(Map<String, Object> obj:orderds){
				int orderId=Integer.parseInt(obj.get("orderdId").toString());
				int clientsId=Integer.parseInt(obj.get("clientsId").toString());
				ErpOrderd orderd=erpOrderdMapper.selectById(orderId);
				ErpClients clients=erpClientsMapper.selectById(clientsId);
				List<ErpOrderdMateriel> orderdMateriels = erpOrderdMaterielMapper.selectByMateriel( orderId, name, brand, 
						specifications, model, place, state, unit);
				if(orderdMateriels.size()>0){
					List<ErpClientsMateriel> clientsMateriels = erpClientsMaterielMapper.selectByMateriel( clients.getId(), name, brand, 
					specifications, model, place, state, unit);
					int materielNumber0 = materielNumber;
					for(ErpOrderdMateriel orderdMateriel:orderdMateriels){
						int MaterielAmount = orderdMateriel.getMaterielAmount();
						if(MaterielAmount > materielNumber){
							MaterielAmount = MaterielAmount-materielNumber;
							materielNumber = 0;
						}else{
							materielNumber = materielNumber-MaterielAmount;
							MaterielAmount = 0;
						}
						orderdMateriel.setMaterielAmount(MaterielAmount);
						if(MaterielAmount==0){
							//已发货完成
							orderdMateriel.setWorkState(1);
						}
						erpOrderdMaterielMapper.updateById(orderdMateriel);
					}
					for(ErpClientsMateriel clientsMateriel:clientsMateriels){
						int MaterielAmount = clientsMateriel.getMaterielAmount()-clientsMateriel.getOutAmount();
						if(MaterielAmount > materielNumber0){
							MaterielAmount = materielNumber0;
						}
						int maxForCount = materielindex+MaterielAmount;
						for(int i=materielindex; i<maxForCount; i++){
							ErpClientsMaterielDetails cmd = new ErpClientsMaterielDetails();
							cmd.setPid(clientsMateriel.getId());
							cmd.setMaterielId(materiels.get(i).getId());
							cmd.setMaterielStudy(0);
							erpClientsMaterielDetailsMapper.insert(cmd);
							if(materielsFD.get(i) != null){
								ErpClientsMaterielDetails cmd0 = new ErpClientsMaterielDetails();
								cmd0.setPid(clientsMateriel.getId());
								cmd0.setMaterielId(materielsFD.get(i).getId());
								cmd0.setMaterielStudy(0);
								erpClientsMaterielDetailsMapper.insert(cmd0);
							}
						}
						materielindex = maxForCount;
					}
					clients.setComeLib(1);
					clients.setOutLib(1);
					erpClientsMapper.updateById(clients);
					
					//保存销售出库与采购订购关系
					ErpFlowClients fc = new ErpFlowClients();
					fc.setFlowSheetid(XSCKSheetId);
					fc.setClientsSheetid(clients.getSheetId());
					fc.setWorkState(0);
					erpFlowClientsMapper.insert(fc);
					
					ErpUser user = erpUserMapper.selectById(userId);
					erpSystemMessageMapper.updateSendFlag(user.getId(), clients.getSheetId());
					
					orderdMateriels = erpOrderdMaterielMapper.selectList(new EntityWrapper<ErpOrderdMateriel>().eq("order_id", orderd.getId()).and().eq("work_state", 0));
					if(orderdMateriels.size() == 0){
						orderd.setWordState(1);
						erpOrderdMapper.updateById(orderd);
					}
					if(materielNumber == 0){
						break a;
					}
				}
			}
		}
		return true;
	}

	@Override
	public String getSheelIdByDate(String time,String type) {
		// TODO Auto-generated method stub
		try {
			time=DataUtil.getStringDate(time);
			String id="";
			if(type.trim().equals("调拨出库")) {
				id="DBCK"+time;
			}else if(type.trim().equals("代销出库")) {
				id="DXCK"+time;
			}else if(type.trim().equals("退货出库")) {
				id="THCK"+time;
			}else if(type.trim().equals("备用出库")) {
				id="BYCK"+time;
			}else if(type.trim().equals("销售出库")) {
				id="XSCK"+time;
			}else if(type.trim().equals("维修出库")) {
				id="WXCK"+time;
			}
			List<ErpMaterielFlow> list=erpMaterielFlowMapper.selectList(new EntityWrapper<ErpMaterielFlow>().like("materiel_flow_sheet_id", id).orderBy("id", false));
			if(list.size()>0) {
				ErpMaterielFlow flow=list.get(0);
				String str=flow.getMaterielFlowSheetId().substring(12, flow.getMaterielFlowSheetId().length());
				str=IDUtils.addOne(str);
				id+=str;
			}else {
				id+="00001";
			}
			return id;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return "";
		}
	}
	
	/**
	 * 修改轮胎档案
	 * @param id
	 * @param mf
	 * @param cost
	 * @return
	 */
	public Integer updateTireArchives(int id, ErpMaterielFlow mf, Double cost, int CostType){
		List<ErpTireArchivesWork> taws = erpTireArchivesWorkMapper.selectList(new EntityWrapper<ErpTireArchivesWork>().eq("tire_id", id).orderBy("work_date", false));
		Double mileage = 0.00;
		String start = "新物品";
		String start0 = "新物品";
		if(taws.size() > 0){
			ErpTireArchivesWork tawOld = taws.get(0);
			mileage = tawOld.getWorkMileage();
			start = tawOld.getWorkTireState();
			start0 = tawOld.getTireState();
		}
		
		
		ErpTireArchivesWork taw = new ErpTireArchivesWork();
		taw.setTireId(id);
		taw.setWorkDate(DataUtil.strToDateLong(mf.getMaterielFlowDate()));
		taw.setWorkSheetId(mf.getMaterielFlowSheetId());
		taw.setWorkMileage(mileage);
		taw.setWorkProject(mf.getFlowType());
		taw.setWorkTireState(start);
		taw.setTireCost(cost);
		taw.setTireState(start0);
		taw.setCostType(CostType);
		taw.setCalculatingMileage(0);
		if(CostType == 2){
			taw.setWorkServiceSector(mf.getSourceCustomerName());
			taw.setTireLocation(mf.getSourceCustomerName()+"-"+mf.getSourceWarehouseName());
			taw.setCustomerId(mf.getCustomerId());
		}else{
			taw.setWorkServiceSector(mf.getCustomerName());
			taw.setTireLocation(mf.getCustomerName()+"-"+mf.getWarehouseName());
			taw.setCustomerId(mf.getSourceCustomerId());
		}
		return erpTireArchivesWorkMapper.insert(taw);
	}
}
